package com.itheima.ums.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mall.exception.BusinessException;
import com.itheima.mall.exception.ErrorResult;
import com.itheima.mall.pojo.*;
import com.itheima.mall.utils.JwtUtils;
import com.itheima.mall.vo.PageResult;
import com.itheima.mall.vo.UserRightsVo;
import com.itheima.ums.interceptor.AdminHolder;
import com.itheima.ums.mapper.*;
import com.itheima.ums.service.UmsAdminService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class UmsAdminServiceImpl implements UmsAdminService {

    @Autowired
    private UmsAdminMapper umsAdminMapper;

    @Autowired
    private UmsRoleMapper umsRoleMapper;

    @Autowired
    private AdminWithRoleMapper adminWithRoleMapper;

    @Autowired
    private RoleWithMenuMapper roleWithMenuMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private AdminLoginLogMapper adminLoginLogMapper;

    /**
     * 用户登录
     *
     * @param admin
     * @return
     */
    public Map login(Admin admin) {
        if (admin.getUsername() == null || admin.getPassword() == null) {
            throw new BusinessException(ErrorResult.loginEmptyError());
        }

        String username = admin.getUsername();
        LambdaQueryWrapper<Admin> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Admin::getUsername, username);
        Admin one = umsAdminMapper.selectOne(queryWrapper);
        if (one != null) {
            //判断前端传来的账号是否已被冻结
            if (one.getStatus() == 0) {
                throw new BusinessException(ErrorResult.loginAccountError());
            }
            //判断密码是否一致
            String pwd = DigestUtils.md5DigestAsHex(admin.getPassword().getBytes());
            if (!one.getPassword().equals(pwd)) {
                throw new BusinessException(ErrorResult.loginPwdError());
            }
        }
        Map map = new HashMap();
        map.put("id", one.getId());
        map.put("username", one.getUsername());
        String token = JwtUtils.getToken(map);
        Map retMap = new HashMap();
        retMap.put("tokenHead", "Bearer ");
        retMap.put("token", token);

        insertLoginLog(one.getId());

        return retMap;
    }

    /**
     * 刷新token
     *
     * @return
     */
    public Map refreshToken() {
        Long adminId = AdminHolder.getAdminId();
        String adminName = AdminHolder.getAdminName();

        Map map = new HashMap();
        map.put("id", adminId);
        map.put("username", adminName);
        String token = JwtUtils.getToken(map);
        Map retMap = new HashMap();
        retMap.put("tokenHead", "Bearer ");
        retMap.put("token", token);

        return retMap;
    }


    /**
     * 记录注册日志
     *
     * @param id
     */
    private void insertLoginLog(Long id) {
        AdminLoginLog adminLoginLog = new AdminLoginLog();
        adminLoginLog.setAdminId(id);
        adminLoginLog.setCreateTime(new Date());
        adminLoginLog.setIp("192.168.0.1");
        adminLoginLog.setAddress("黑马程序员");
        adminLoginLog.setUserAgent("谷歌");
        adminLoginLogMapper.insert(adminLoginLog);
    }

    /**
     * 根据用户id查询用户权限信息
     *
     * @return
     */
    @Override
    public UserRightsVo info() {
        //获取用户id
        Long adminId = AdminHolder.getAdminId();
        //根据id查询用户
        Admin admin = umsAdminMapper.selectById(adminId);
        UserRightsVo vo = new UserRightsVo();
        if (admin != null) {
            vo.setUsername(admin.getUsername());
            vo.setIcon(admin.getIcon());
            //查询用户角色关联表，查出角色id
            LambdaQueryWrapper<AdminRoleRelation> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(AdminRoleRelation::getAdminId, admin.getId());
            AdminRoleRelation relation = adminWithRoleMapper.selectOne(queryWrapper);
            List<AdminRoleRelation> list1 = adminWithRoleMapper.selectList(queryWrapper);
            if (CollUtil.isEmpty(list1)) {

            }
            if (relation != null) {
                List list = new ArrayList();
                //根据角色id查询用户角色
                Role role = umsRoleMapper.selectById(relation.getRoleId());
                list.add(role.getName());
                vo.setRoles(list);
                //根据用户角色id查询角色目录关联表
                LambdaQueryWrapper<RoleMenuRelation> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(RoleMenuRelation::getRoleId, relation.getRoleId());
                //查询出角色对应的目录结构
                List<RoleMenuRelation> roleMenuRelations = roleWithMenuMapper.selectList(queryWrapper1);
                List<Long> menuIds = CollUtil.getFieldValues(roleMenuRelations, "menuId", Long.class);
                if (!CollUtil.isEmpty(menuIds)) {
                    List<Menu> menus = menuMapper.selectBatchIds(menuIds);
                    vo.setMenus(menus);
                }
            }
        }
        return vo;
    }

    /**
     * 根据用户名或姓名分页获取用户列表
     *
     * @param pageNum
     * @param pageSize
     * @param keyword
     * @return
     */
    public PageResult list(Integer pageNum, Integer pageSize, String keyword) {
        Page page = new Page(pageNum, pageSize);
        LambdaQueryWrapper<Admin> queryWrapper = new LambdaQueryWrapper<>();
        //关键字存在就匹配关键字查询
        queryWrapper.like(StringUtils.isNotEmpty(keyword), Admin::getUsername, keyword).or()
                .like(StringUtils.isNotEmpty(keyword), Admin::getNickName, keyword);

        umsAdminMapper.selectPage(page, queryWrapper);
        List<Admin> list = page.getRecords();
        list = list.stream().map(item -> {
            LambdaQueryWrapper<AdminLoginLog> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(AdminLoginLog::getAdminId, item.getId());
            boolean exists = adminLoginLogMapper.exists(queryWrapper1);
            if (exists) {
                queryWrapper1.orderByDesc(AdminLoginLog::getCreateTime);
                AdminLoginLog adminLoginLog = adminLoginLogMapper.selectList(queryWrapper1).get(0);
                if (adminLoginLog != null) {
                    item.setLoginTime(adminLoginLog.getCreateTime());
                }
            }

            return item;
        }).collect(Collectors.toList());


        return new PageResult(pageNum, pageSize, (int) page.getTotal(), list);
    }

    //登出功能
    public void logout() {
        AdminHolder.remove();
    }

    /**
     * 注册用户
     *
     * @param admin
     * @return
     */
    public Admin register(Admin admin) {
        //前端传来空数据，直接提示错误
        if (admin == null) {
            throw new BusinessException(ErrorResult.registerEmptyError());
        }
        String username = admin.getUsername();
        LambdaQueryWrapper<Admin> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(username), Admin::getUsername, username);
        boolean exists = umsAdminMapper.exists(queryWrapper);
        //注册的用户名存在，提升错误
        if (exists) {
            throw new BusinessException(ErrorResult.registerError());
        }

        String password = DigestUtils.md5DigestAsHex(admin.getPassword().getBytes());
        admin.setPassword(password);
        admin.setCreateTime(new Date());
        umsAdminMapper.insert(admin);

        return admin;
    }

    /**
     * 删除用户
     *
     * @param id
     * @return
     */
    public Integer deleteById(Long id) {
        LambdaQueryWrapper<AdminRoleRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AdminRoleRelation::getAdminId, id);
        boolean exists = adminWithRoleMapper.exists(queryWrapper);
        if (exists) {
            adminWithRoleMapper.delete(queryWrapper);
        }

        int count = umsAdminMapper.deleteById(id);
        return count;
    }

    /**
     * 查询用户角色
     *
     * @param adminId
     * @return
     */
    public List<Role> getRoleInfoById(Long adminId) {
        //查询用户角色关联表，通过用户id查出对应的角色id
        LambdaQueryWrapper<AdminRoleRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AdminRoleRelation::getAdminId, adminId);
        List<AdminRoleRelation> relations = adminWithRoleMapper.selectList(queryWrapper);

        List<Long> roleIds = CollUtil.getFieldValues(relations, "roleId", Long.class);
        //通过角色id查询角色
        if (CollUtil.isEmpty(roleIds)) {
            return new ArrayList<>();
        }
        List<Role> roles = umsRoleMapper.selectBatchIds(roleIds);

        return roles;
    }

    /**
     * 分配角色
     *
     * @param adminId
     * @param roleIds
     * @return
     */
    public Integer updateRole(Long adminId, List<Long> roleIds) {
        LambdaQueryWrapper<AdminRoleRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(adminId != null, AdminRoleRelation::getAdminId, adminId);

        if (!CollUtil.isEmpty(roleIds)) {
            adminWithRoleMapper.delete(queryWrapper);
        }


        int count = 0;
        if (!CollUtil.isEmpty(roleIds)) {
            for (Long roleId : roleIds) {
                if (roleId != null) {
                    AdminRoleRelation relation = new AdminRoleRelation();
                    relation.setRoleId(roleId);
                    relation.setAdminId(adminId);
                    count = adminWithRoleMapper.insert(relation);
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 修改角色
     *
     * @param admin
     * @param id
     * @return
     */
    public Integer updateById(Admin admin, Long id) {
        Admin admin1 = umsAdminMapper.selectById(id);
        if (admin1 != null) {
            if (!admin1.getPassword().equals(admin.getPassword())) {
                String pwd = DigestUtils.md5DigestAsHex(admin.getPassword().getBytes());
                admin.setPassword(pwd);
            }
        }

        LambdaQueryWrapper<Admin> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Admin::getId, id);

        int count = umsAdminMapper.update(admin, queryWrapper);

        return count;
    }

    //获取指定用户信息
    public Admin getAdminById(Long id) {
        return umsAdminMapper.selectById(id);
    }

    //修改帐号状态
    public Integer updateStatus(Long id, Long status) {
        LambdaUpdateWrapper<Admin> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Admin::getStatus, status).eq(Admin::getId, id);
        return umsAdminMapper.update(null, updateWrapper);
    }
}
